/*
 * Date：10/23/18 10:50 PM
 * Author: guomw
 *
 */

package com.treasure.mall.zbqmallmanager.controller;

import com.alibaba.fastjson.JSON;
import com.treasure.mall.biz.base.UserDetails;
import com.treasure.mall.biz.entity.statistics.DealAmountStatisticsPO;
import com.treasure.mall.biz.entity.statistics.OrderStatisticsPO;
import com.treasure.mall.biz.service.core.auth.SystemService;
import com.treasure.mall.biz.service.core.statistics.DealAmountStatisticsService;
import com.treasure.mall.biz.service.core.statistics.OrderStatisticsService;
import com.treasure.mall.biz.service.core.user.MerchantService;
import com.treasure.mall.biz.service.core.user.UserService;
import com.treasure.mall.zbq.common.Jsr310Utils;
import com.treasure.mall.zbq.common.RandomUtils;
import com.treasure.mall.zbq.common.RegexUtils;
import com.treasure.mall.zbq.common.base.ApiResult;
import com.treasure.mall.zbq.common.constant.Constant;
import com.treasure.mall.zbq.common.ienum.auth.RoleEnum;
import com.treasure.mall.zbqmallmanager.config.SecurityConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

/**
 * @author guomw
 * @date 2018/9/6
 */
@Controller
public class IndexController {
    @Value("${zbq.domain.admin}")
    private String ADMIN_DOMAIN;
    @Value("${zbq.domain.merchant}")
    private String MERCHANT_DOMAIN;
    @Value("${zbq.domain.org}")
    private String ORG_DOMAIN;

    @Autowired
    private SystemService systemService;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private OrderStatisticsService orderStatisticsService;
    @Autowired
    private MerchantService merchantService;
    @Autowired
    private UserService userService;
    @Autowired
    private DealAmountStatisticsService dealAmountStatisticsService;

    private Environment env;

    @Autowired
    public IndexController(Environment environment) {
        env = environment;
    }

    @RequestMapping(value = {"login"})
    public String index(HttpServletRequest request, Model model) {
        StringBuffer url = request.getRequestURL();
        String domain = url.delete(url.length() - request.getRequestURI().length(), url.length()).toString();

        String role = RoleEnum.ADMIN.getCode();
        String title = Constant.SYSTEM_ADMIN_NAME;
        if (domain.contains(MERCHANT_DOMAIN)) {
            role = RoleEnum.MERCHANT.getCode();
            title = Constant.SYSTEM_MERCHANT_NAME;
        }
        if (domain.contains(ORG_DOMAIN)) {
            role = RoleEnum.ORG_CENTER.getCode();
            title = Constant.SYSTEM_ORG_NAME;
        }

        model.addAttribute("role", role);
        model.addAttribute("title", title);
        return "login";
    }

    @RequestMapping(SecurityConfig.LOGIN_FAILED_URL)
    public String loginFailed(HttpServletRequest request, RedirectAttributes attributes) {
        attributes.addFlashAttribute("errMsg", request.getSession().getAttribute("SPRING_SECURITY_LAST_EXCEPTION"));
        attributes.addFlashAttribute("failedFlag", true);

        return "redirect:login";
    }

    private String getErrorText(Integer code) {
        String text = "403 Forbidden";
        switch (code) {
            case 200:
                text = "success";
                break;
            case 500:
                text = "当前密码不正确";
                break;
            case 0:
                text = "";
                break;
            default:
                break;
        }
        return text;
    }

    @RequestMapping(value = {"/home", "/"})
    public String home(@AuthenticationPrincipal UserDetails userDetails) {
        switch (userDetails.getRoleType()) {
            case MERCHANT:
                return "merchant_main";
            case ORG_CENTER:
                return "org_main";
            default:
                return "main";
        }
    }

    /**
     * 商家的桌面
     *
     * @param model
     * @param userDetails
     * @return
     */
    @GetMapping("/merchant/desktop")
    public String merchantDesktop(Model model, @AuthenticationPrincipal UserDetails userDetails) {
        model.addAttribute("data", orderStatisticsService.orderStatistics(userDetails));

        return "merchant_desktop";
    }

    @GetMapping("/desktop")
    public String desktop(Model model, @AuthenticationPrincipal UserDetails userDetails) {
        model.addAttribute("data", orderStatisticsService.orderStatistics(userDetails));
        model.addAttribute("userData", userService.getStatisticsData());
        List<DealAmountStatisticsPO> dealAmount = dealAmountStatisticsService.sevenDays();
        List<String> dates = dealAmount.stream()
                .map(p -> Jsr310Utils.Date.asString(p.getDate())).collect(Collectors.toList());


        model.addAttribute("dealAmountJson", JSON.toJSONString(dealAmount));
        model.addAttribute("dealAmount", dealAmount);
        model.addAttribute("dates", dates);

        List<OrderStatisticsPO> orderCount = orderStatisticsService.sevenDays();
        model.addAttribute("orderCountJson", JSON.toJSONString(orderCount));
        model.addAttribute("orderCount", orderCount);

        return "desktop";
    }


    @RequestMapping("/bank")
    public String bank(@RequestParam(required = false, defaultValue = "403") Integer code,
                       Model model) {
        model.addAttribute("errorCode", code == 0 ? "" : code.toString());
        model.addAttribute("errorText", getErrorText(code));
        return "bank";
    }

    /**
     * 退出注销
     *
     * @param request
     * @return
     */
    @RequestMapping(value = "/logout")
    public String logout(HttpServletRequest request) {
        request.getSession().invalidate();
        return "redirect:/login";
    }

    @PostMapping("/changePass")
    @ResponseBody
    public ApiResult changePassword(String origin, String newPass, HttpServletRequest request, @AuthenticationPrincipal UserDetails userDetails) {

        if (userDetails.getRoleType().equals(RoleEnum.MERCHANT)) {
            merchantService.changePassword(origin, newPass);
        } else {
            if (!passwordEncoder.matches(origin, userDetails.getPassword())) {
                return ApiResult.error("当前密码错误");
            }
            if (!RegexUtils.checkPassword(newPass, userDetails.getUsername())) {
                return ApiResult.error("密码必须8-16字符，并且包含字母与数字");
            }
            systemService.modifyManagerPassword(userDetails.getId().intValue(), passwordEncoder.encode(newPass));
        }
        request.getSession().invalidate();
        return ApiResult.ok();
    }


    /**
     * 获取图片验证码
     *
     * @param request
     * @param response
     * @throws IOException
     */
    @RequestMapping(value = {"/verifyCode"}, method = RequestMethod.GET)
    public void verifyCode(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 创建一张空白的图片
        BufferedImage image = new BufferedImage(100, 30, BufferedImage.TYPE_INT_RGB);
        // 获取该图片的笔画
        Graphics g = image.getGraphics();

        // 绘制背景
        // 设置画笔的颜色
        Random r = new Random();
        g.setColor(new Color(249, 249, 250));
        // 绘制一个实心额矩形区域
        g.fillRect(0, 0, 100, 30);
        // 绘制内容
        g.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255)));
        g.setFont(new Font(null, Font.BOLD, 25));

        // 生成验证码
        String num = RandomUtils.randomString(5);

        // 验证码的内容保存到session中
        HttpSession session = request.getSession();
        System.out.println(session.getId());
        session.setAttribute("verifyCode", num);
        FontMetrics fontMetrics = g.getFontMetrics();
        int stringWidth = fontMetrics.stringWidth(num);
        int stringAscent = fontMetrics.getAscent();
        int stringDescent = fontMetrics.getDescent();
        //设置内容居中
        g.drawString(num, 100 / 2 - stringWidth / 2, 30 / 2 + (stringAscent - stringDescent) / 2);

        // 将内存中的图片发送到客户端
        response.setContentType("image/jpg");
        OutputStream ops = response.getOutputStream();
        ImageIO.write(image, "jpeg", ops);
    }

}
